#include"ChunkRender.h"
#include"World.h"

#include<iostream>
namespace Craft
{

	namespace
	{
		const GLint   VERTEX_AO_LEVEL = 4;
		const GLfloat VERTEX_AO_CASE[VERTEX_AO_LEVEL] = { 0.33f, 0.6f, 0.8f, 1.0f };
		bool  bVertexAO = true;
	}
								
	VertexArrays ChunkRender::va(41000, VertexFormat(3, 3, 0, 2));
	ElementsBuffe ChunkRender::eb(41000);

	ChunkRender::ChunkRender(Chunk* chunk):
				m_chunk(chunk),
				m_buffer()
	{
		va.clear();
		eb.clear();
		tri_render_count = 0;

		for_range_glmVec3(glm::vec3(0), glm::vec3(m_chunk->get_width()), [&,chunk](const glm::vec3& pos)
		{
			Block block = chunk->get_block(glm::vec3(pos.x, pos.y, pos.z));

			switch (block.get_type())
			{
			case tBLOCK:
				// 非空气块才渲染
				if (block.get_Id() > 0)
					BlockRenderManger::render(block.get_Id() - 1, block.get_pos(), this);
				break;
				// 植物块有不同渲染方式，未完成
			case tPLANT:
				BlockRenderManger::render(block.get_Id() - 1, block.get_pos(), this);
				break;
			default:
				break;
			}
		});

		std::cout << tri_render_count << std::endl;
		m_buffer = std::move(VertexBuffer(va, eb));
	}

	ChunkRender::ChunkRender(ChunkRender&& rhs) :
		m_buffer(std::move(rhs.m_buffer)),
		m_chunk(rhs.m_chunk)
	{
	}

	ChunkRender& ChunkRender::operator=(ChunkRender&& rhs)
	{
		m_buffer = std::move(rhs.m_buffer);
		m_chunk = rhs.m_chunk;

		return *this;
	}

	ChunkRender::~ChunkRender()
	{
		va.clear();
		eb.clear();

	}

	void ChunkRender::render(Shader shader)
	{
		m_buffer.render(shader);
	}

	/*
		@brief 判断重叠面是否渲染，目前仅判断两个方块是否不同
	*/
	bool ChunkRender::adjacent_test(Block curr, Block neigh)
	{
		return  curr.get_Id() != neigh.get_Id();
	}


	void ChunkRender::add_Block(TexInfo tex[] , glm::vec3 pos)
	{
		GLfloat chunk_width = m_chunk->get_width();

		Block currBlock = m_chunk->get_block(pos);
		glm::vec3 w_pos = currBlock.get_world_pos();

		// get the neighbors of current block
		Block neighbors[6] = {
			pos.x == chunk_width - 1 ? m_chunk->get_world()->get_block_byWorldPos(w_pos + glm::vec3(1.0f, 0.0f, 0.0f)) : 
									   m_chunk->get_block(pos + glm::vec3(1.0f, 0.0f, 0.0f)), 					// right
			pos.x == 0 ?			   m_chunk->get_world()->get_block_byWorldPos(w_pos + glm::vec3(-1.0f, 0.0f, 0.0f)) :
									   m_chunk->get_block(pos + glm::vec3(-1.0f, 0.0f, 0.0f)), 									// left
			pos.y == chunk_width - 1 ? m_chunk->get_world()->get_block_byWorldPos(w_pos + glm::vec3(0.0f, 1.0f, 0.0f)) : 
									   m_chunk->get_block(pos + glm::vec3(0.0f, 1.0f, 0.0f)), 					// top
			pos.y == 0 ?               m_chunk->get_world()->get_block_byWorldPos(w_pos + glm::vec3(0.0f, -1.0f, 0.0f)) :
									   m_chunk->get_block(pos + glm::vec3(0.0f, -1.0f, 0.0f)), 									// bottom
			pos.z == chunk_width - 1 ? m_chunk->get_world()->get_block_byWorldPos(w_pos + glm::vec3(0.0f, 0.0f, 1.0f)) : 
									   m_chunk->get_block(pos + glm::vec3(0.0f, 0.0f, 1.0f)), 					// back
			pos.z == 0 ?			   m_chunk->get_world()->get_block_byWorldPos(w_pos + glm::vec3(0.0f, 0.0f, -1.0f)) : 
									   m_chunk->get_block(pos + glm::vec3(0.0f, 0.0f, -1.0f))									// front

		};

		unsigned int i = va.get_vertex_count();

		// s0 d[0] w0 d[1] / s1 d[2] w1 d[3]
		// right
		if (adjacent_test(currBlock, neighbors[0]))
		{
			glm::vec3 position[4] = 
			{
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 1.0f, w_pos.z + 0.0f),  // lt   	   0____3
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 0.0f, w_pos.z + 0.0f),  // lb	 	   |  /|
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 0.0f, w_pos.z + 1.0f),  // rb		   | / |
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 1.0f, w_pos.z + 1.0f)   // rt    	   1/__|2  
			};

			// 明亮度为该面面对的方块的亮度
			//GLfloat brightness = GLfloat(neighbors[0].get_lightValue() / BLOCK_MAX_LIGHT);

			// indic
			GLuint indices[6] = {
				i+3, i + 1, i,
				i + 3, i + 2, i + 1
			};
			
	
			GLfloat occlusion[4] = {
				neighbors[0].get_Id() ?1.0f : vertexAO(position[0], glm::vec3(0.0f, -1.0f, -1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
				neighbors[0].get_Id() ?1.0f : vertexAO(position[1], glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, -1.0f, -1.0f)),
				neighbors[0].get_Id() ?1.0f : vertexAO(position[2], glm::vec3(0.0f, -1.0f, -1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
				neighbors[0].get_Id() ?1.0f : vertexAO(position[3], glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f)),
			};
			
			// fix the occlusion,which is  flipping the quad
			if ((occlusion[0] + occlusion[2]) > (occlusion[1] + occlusion[3]))
			{
				indices[1] = i + 2;
				indices[3] = i;

			}
			va.addPrimitive(4,
			{	// pos									  // color		    // tex
				position[0].x, position[0].y, position[0].z, occlusion[0] , 0.0f, 0.0f, tex[0].d[2], tex[0].d[1],
				position[1].x, position[1].y, position[1].z, occlusion[1] , 1.0f, 0.0f, tex[0].d[2], tex[0].d[3],
				position[2].x, position[2].y, position[2].z, occlusion[2] , 0.0f, 1.0f, tex[0].d[0], tex[0].d[3],
				position[3].x, position[3].y, position[3].z, occlusion[3] , 1.0f, 0.0f, tex[0].d[0], tex[0].d[1]
			});

			eb.addIndices(6, indices);
			i += 4;

			// 渲染的三角形计数
			tri_render_count += 2;
		}


		// left
		if (adjacent_test(currBlock, neighbors[1]))
		{

			glm::vec3 position[4] =
			{
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 1.0f, w_pos.z + 0.0f),	// lt   	   0____3	
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 0.0f, w_pos.z + 0.0f),	// lb	 	   |  /|
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 0.0f, w_pos.z + 1.0f),	// rb		   | / |
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 1.0f, w_pos.z + 1.0f)		// rt    	   1/__|2  
			};

			// 明亮度为该面面对的方块的亮度
			//GLfloat brightness = GLfloat(neighbors[1].get_lightValue() / BLOCK_MAX_LIGHT);

			// indices
			GLuint indices[6] = {
				i, i + 1, i + 3,
				i + 1, i + 2, i + 3
			};

			GLfloat occlusion[4] = {
				neighbors[1].get_Id() ? 1.0f : vertexAO(position[0], glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, -1.0f)),
				neighbors[1].get_Id() ? 1.0f : vertexAO(position[1], glm::vec3(-1.0f, 0.0f, -1.0f), glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec3(-1.0f, -1.0f, -1.0f)),
				neighbors[1].get_Id() ? 1.0f : vertexAO(position[2], glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(-1.0f, -1.0f, 0.0f)),
				neighbors[1].get_Id() ? 1.0f : vertexAO(position[3], glm::vec3(-1.0f, 0.0f, -1.0f), glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f)),
			};

			// fix the occlusion
			if ((occlusion[0] + occlusion[2]) > (occlusion[1] + occlusion[3]))
			{
				indices[1] = i + 2;
				indices[5] = i;
			}

			va.addPrimitive(4,
			{
				position[0].x, position[0].y, position[0].z, occlusion[0] , 0.0f, 0.0f, tex[1].d[2], tex[1].d[1],
				position[1].x, position[1].y, position[1].z, occlusion[1] , 1.0f, 0.0f, tex[1].d[2], tex[1].d[3],
				position[2].x, position[2].y, position[2].z, occlusion[2] , 0.0f, 1.0f, tex[1].d[0], tex[1].d[3],
				position[3].x, position[3].y, position[3].z, occlusion[3] , 1.0f, 0.0f, tex[1].d[0], tex[1].d[1]
			});

			eb.addIndices(6,indices);
			i += 4;
			tri_render_count += 2;
		}

		// 3 top
		if (adjacent_test(currBlock, neighbors[2]))
		{
			// position
			glm::vec3 position[4] =
			{
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 1.0f, w_pos.z + 0.0f),			// lb    	   1____2	
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 1.0f, w_pos.z + 1.0f),			// lt	 	   |\  |
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 1.0f, w_pos.z + 1.0f),			// rt		   | \ |
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 1.0f, w_pos.z + 0.0f)				// rb    	   0__\|3  
			};
			
			// 明亮度为该面面对的方块的亮度
			//GLfloat brightness = GLfloat(neighbors[2].get_lightValue() / BLOCK_MAX_LIGHT);

			// indices
			GLuint indices[6] = {
				i, i + 1, i + 3,
				i + 1, i + 2, i + 3
			};

			// occlusion
			GLfloat occlusion[4] = {
				neighbors[2].get_Id() ? 1.0f : vertexAO(position[0], glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, -1.0f)),
				neighbors[2].get_Id() ? 1.0f : vertexAO(position[1], glm::vec3(-1.0f, 0.0f, -1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f)),
				neighbors[2].get_Id() ? 1.0f : vertexAO(position[2], glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f)),
				neighbors[2].get_Id() ? 1.0f : vertexAO(position[3], glm::vec3(-1.0f, 0.0f, -1.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f))
			};

			// fix the occlusion
			if ((occlusion[2] + occlusion[0]) > (occlusion[1] + occlusion[3]) )
			{
				indices[1] = i + 2;
				indices[5] = i;
			}

			// add vertex to array
			va.addPrimitive(4,
			{
				position[0].x, position[0].y, position[0].z, occlusion[0] , 0.0f, 0.0f, tex[2].d[2], tex[2].d[1],
				position[1].x, position[1].y, position[1].z, occlusion[1] , 1.0f, 0.0f, tex[2].d[2], tex[2].d[3],
				position[2].x, position[2].y, position[2].z, occlusion[2] , 0.0f, 1.0f, tex[2].d[0], tex[2].d[3],
				position[3].x, position[3].y, position[3].z, occlusion[3] , 1.0f, 0.0f, tex[2].d[0], tex[2].d[1]
			});

			// add indices to array
			eb.addIndices(6,indices );
			i += 4;
			tri_render_count += 2;
		}


		// 4 bottom
		if (adjacent_test(currBlock, neighbors[3]))
		{
			// position
			glm::vec3 position[4] =
			{
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 0.0f, w_pos.z + 1.0f),		// lt    	   3____0
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 0.0f, w_pos.z + 0.0f),		// lb	 	   |\  |
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 0.0f, w_pos.z + 0.0f),        // rb		   | \ |
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 0.0f, w_pos.z + 1.0f)			// rt    	   2__\|1  
			};

			// 明亮度为该面面对的方块的亮度
			GLfloat brightness = GLfloat(neighbors[3].get_lightValue() / BLOCK_MAX_LIGHT);

			// indices
			GLuint indices[6] = {
				i, i + 1, i + 3,
				i + 1, i + 2, i + 3
			};

			// occlusion
			GLfloat occlusion[4] = {
				neighbors[3].get_Id() ? 1.0f : vertexAO(position[0], glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(-1.0f, -1.0f, 0.0f)),
				neighbors[3].get_Id() ? 1.0f : vertexAO(position[1], glm::vec3(0.0f, -1.0f, -1.0f), glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec3(-1.0f, -1.0f, -1.0f)),
				neighbors[3].get_Id() ? 1.0f : vertexAO(position[2], glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, -1.0f, -1.0f)),
				neighbors[3].get_Id() ? 1.0f : vertexAO(position[3], glm::vec3(0.0f, -1.0f, -1.0f), glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f))
			};


			// fix the occlusion
			if ((occlusion[2] + occlusion[0]) > (occlusion[1] + occlusion[3]))
			{
				indices[1] = i + 2;
				indices[5] = i;
			}

			// add vertex to array
			va.addPrimitive(4,
			{
				position[0].x, position[0].y, position[0].z, occlusion[0] , 0.0f, 0.0f, tex[3].d[2], tex[3].d[1],
				position[1].x, position[1].y, position[1].z, occlusion[1] , 1.0f, 0.0f, tex[3].d[2], tex[3].d[3],
				position[2].x, position[2].y, position[2].z, occlusion[2] , 0.0f, 1.0f, tex[3].d[0], tex[3].d[3],
				position[3].x, position[3].y, position[3].z, occlusion[3] , 1.0f, 0.0f, tex[3].d[0], tex[3].d[1]
			});

			eb.addIndices(6, indices);
			i += 4;
			tri_render_count += 2;
		}

		// s0 d[0] w0 d[1] / s1 d[2] w1 d[3]
		// 5 back
		if (adjacent_test(currBlock, neighbors[4]))
		{
			glm::vec3 position[4] =
			{
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 1.0f, w_pos.z + 1.0f),		// rt    0	   3____0
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 0.0f, w_pos.z + 1.0f),		// rb	 1	   |\  |
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 0.0f, w_pos.z + 1.0f),		// lb		   | \ |
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 1.0f, w_pos.z + 1.0f)			// lt    2	   2__\|1  
			};
	

			// 明亮度为该面面对的方块的亮度
			//GLfloat brightness = GLfloat(neighbors[4].get_lightValue() / BLOCK_MAX_LIGHT);

			GLfloat occlusion[4] = {
				neighbors[4].get_Id() ? 1.0f : vertexAO(position[0], glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f)),
				neighbors[4].get_Id() ? 1.0f : vertexAO(position[1], glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
				neighbors[4].get_Id() ? 1.0f : vertexAO(position[2], glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(-1.0f, -1.0f, 0.0f)),
				neighbors[4].get_Id() ? 1.0f : vertexAO(position[3], glm::vec3(-1.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f))

			};
			// indices
			GLuint indices[6] = {
				i  +3, i + 1, i,
				i + 3, i + 2, i + 1
			};

			// fix the occlusion
			if ((occlusion[2] + occlusion[0]) > (occlusion[1] + occlusion[3]))
			{
				indices[1] = i + 2;
				indices[3] = i;
			}

			va.addPrimitive(4,
			{
				position[0].x, position[0].y, position[0].z, occlusion[0] , 0.0f, 0.0f, tex[4].d[2], tex[4].d[1],
				position[1].x, position[1].y, position[1].z, occlusion[1] , 1.0f, 0.0f, tex[4].d[2], tex[4].d[3],
				position[2].x, position[2].y, position[2].z, occlusion[2] , 0.0f, 1.0f, tex[4].d[0], tex[4].d[3],
				position[3].x, position[3].y, position[3].z, occlusion[3] , 1.0f, 0.0f, tex[4].d[0], tex[4].d[1]
			});

			eb.addIndices(6, indices);
			i += 4;
			tri_render_count += 2;
		}

		// 6 front

		if (adjacent_test(currBlock, neighbors[5]))
		{
			glm::vec3 position[4] =
			{
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 1.0f, w_pos.z + 0.0f),			// rt    0	   3____0	
				glm::vec3(w_pos.x + 1.0f, w_pos.y + 0.0f, w_pos.z + 0.0f),			// rb	 1	   |\  |
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 0.0f, w_pos.z + 0.0f),			// lb		   | \ |
				glm::vec3(w_pos.x + 0.0f, w_pos.y + 1.0f, w_pos.z + 0.0f)				// lt    2	   2__\|1  
			};

			// 明亮度为该面面对的方块的亮度
			//GLfloat brightness = GLfloat(neighbors[5].get_lightValue() / BLOCK_MAX_LIGHT);

			// indices
			GLuint indices[6] = {
				i, i + 1, i + 3,
				i + 1, i + 2, i + 3
			};

			GLfloat occlusion[4] = {
				neighbors[5].get_Id() ? 1.0f : vertexAO(position[0], glm::vec3(-1.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, -1.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
				neighbors[5].get_Id() ? 1.0f : vertexAO(position[1], glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, -1.0f)),
				neighbors[5].get_Id() ? 1.0f : vertexAO(position[2], glm::vec3(-1.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, -1.0f), glm::vec3(-1.0f, -1.0f, -1.0f)),
				neighbors[5].get_Id() ? 1.0f : vertexAO(position[3], glm::vec3(-1.0f, -1.0f, -1.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(-1.0f, 0.0f, -1.0f))
			};

			// fix the occlusion
			if ((occlusion[2] + occlusion[0]) > (occlusion[3] + occlusion[1]))
			{
				indices[1] = i + 2;
				indices[5] = i;
			}


			va.addPrimitive(4,
			{
				position[0].x, position[0].y, position[0].z, occlusion[0] , 0.0f, 0.0f, tex[5].d[2], tex[5].d[1],
				position[1].x, position[1].y, position[1].z, occlusion[1] , 1.0f, 0.0f, tex[5].d[2], tex[5].d[3],
				position[2].x, position[2].y, position[2].z, occlusion[2] , 0.0f, 1.0f, tex[5].d[0], tex[5].d[3],
				position[3].x, position[3].y, position[3].z, occlusion[3] , 1.0f, 0.0f, tex[5].d[0], tex[5].d[1]
			});

			eb.addIndices(6,indices);
			i += 4;
			tri_render_count += 2;
		}


	}

	/*
		@brief 渲染更新，在存在chunk或block更新时，调用此函数
			   重新填充buffer数据
	*/
	void ChunkRender::render_update()
	{
		va.clear();
		eb.clear();

		GLdouble currtime = glfwGetTime();

		for_range_glmVec3(glm::vec3(0), glm::vec3(m_chunk->get_width()), [&](const glm::vec3& pos)
		{
			Block block = m_chunk->get_block(glm::vec3(pos.x, pos.y, pos.z));
			
			switch (block.get_type())
			{
			case tBLOCK:
				// 非空气块才渲染  
				if (block.get_Id() > 0)
				{
					BlockRenderManger::render(block.get_Id() - 1, block.get_pos(), this);
					
				}
				break;
				// 植物块有不同渲染方式，未完成
			case tPLANT:
				BlockRenderManger::render(block.get_Id() - 1, block.get_pos(), this);
				break;
			default:
				break;
			}
		});
	
		std::cout << "BlockRenderManger update time: " << glfwGetTime() - currtime << std::endl;

		m_buffer.updateVA(va);
		m_buffer.updateEB(eb);
	}



	/*
	@brief judge the vertex's case to caculate the occlusion
			一种想法是，要计算一个顶点的情况，只要考虑这个顶点方向全部
	*/
	GLfloat ChunkRender::vertexAO(const glm::vec3& pos, const glm::vec3& offset1, const glm::vec3& offset2, const glm::vec3&corner)
	{
		if (!bVertexAO)
		{
			return VERTEX_AO_CASE[3];
		}


		glm::vec3 side1  = pos + offset1;
		glm::vec3 side2 = pos + offset2;
		glm::vec3 cor = pos + corner ;

		Block bSide1 = m_chunk->get_world()->get_block_byWorldPos(side1);
		Block bSide2 = m_chunk->get_world()->get_block_byWorldPos(side2);
		Block bCorner = m_chunk->get_world()->get_block_byWorldPos(cor);

		GLuint s1 = (bSide1.get_Id() && bSide1.get_type() != tPLANT) ? 1 : 0;
		GLuint s2 = (bSide2.get_Id() && bSide2.get_type() != tPLANT) ? 1 : 0;
		GLuint co = (bCorner.get_Id() && bCorner.get_type() != tPLANT) ? 1 : 0;

		if (s1 & s2)
		{
			return VERTEX_AO_CASE[0];
		}

		return VERTEX_AO_CASE[VERTEX_AO_LEVEL - 1 - s1 - s2 - co];
	}


	void ChunkRender::add_Plant(TexInfo tex, glm::vec3 pos)
	{
		unsigned int i = va.get_vertex_count();
		Block currBlock = m_chunk->get_block(pos);

		// s0 d[0] w0 d[1] / s1 d[2] w1 d[3]
		// right
		va.addPrimitive(4,
		{	// pos									  // color		    // tex
			pos.x + 0.0f, pos.y + 1.0f, pos.z + 1.0f, 1.0f, 0.0f, 0.0f, tex.d[2], tex.d[1],
			pos.x + 0.0f, pos.y + 0.0f, pos.z + 1.0f, 1.0f, 1.0f, 0.0f, tex.d[2], tex.d[3],
			pos.x + 1.0f, pos.y + 0.0f, pos.z + 0.0f, 1.0f, 0.0f, 1.0f, tex.d[0], tex.d[3],
			pos.x + 1.0f, pos.y + 1.0f, pos.z + 0.0f, 1.0f, 1.0f, 0.0f, tex.d[0], tex.d[1]
		});

		eb.addIndices(6, {
			i, i + 1, i + 3,
			i + 1, i + 2, i + 3
		});
		i += 4;

		va.addPrimitive(4,
		{	// pos									  // color		    // tex
			pos.x + 1.0f, pos.y + 1.0f, pos.z + 0.0f, 1.0f, 1.0f, 0.0f, tex.d[0], tex.d[1],
			pos.x + 1.0f, pos.y + 0.0f, pos.z + 0.0f, 1.0f, 0.0f, 1.0f, tex.d[0], tex.d[3],
			pos.x + 0.0f, pos.y + 0.0f, pos.z + 1.0f, 1.0f, 1.0f, 0.0f, tex.d[2], tex.d[3],
			pos.x + 0.0f, pos.y + 1.0f, pos.z + 1.0f, 1.0f, 0.0f, 0.0f, tex.d[2], tex.d[1]
		});

		eb.addIndices(6, {
			i, i + 1, i + 3,
			i + 1, i + 2, i + 3
		});
		i += 4;

		tri_render_count += 2;

		// s0 d[0] w0 d[1] / s1 d[2] w1 d[3]
		// right
		va.addPrimitive(4,
		{	// pos									  // color		    // tex
			pos.x + 0.0f, pos.y + 1.0f, pos.z + 0.0f, 1.0f, 0.0f, 0.0f, tex.d[0], tex.d[1],
			pos.x + 0.0f, pos.y + 0.0f, pos.z + 0.0f, 1.0f, 1.0f, 0.0f, tex.d[0], tex.d[3],
			pos.x + 1.0f, pos.y + 0.0f, pos.z + 1.0f, 1.0f, 0.0f, 1.0f, tex.d[2], tex.d[3],
			pos.x + 1.0f, pos.y + 1.0f, pos.z + 1.0f, 1.0f, 1.0f, 0.0f, tex.d[2], tex.d[1]
		});

		eb.addIndices(6, {
			i, i + 1, i + 3,
			i + 1, i + 2, i + 3
		});
		i += 4;

		va.addPrimitive(4,
		{	// pos									  // color		    // tex
			pos.x + 1.0f, pos.y + 1.0f, pos.z + 1.0f, 1.0f, 1.0f, 0.0f, tex.d[2], tex.d[1],
			pos.x + 1.0f, pos.y + 0.0f, pos.z + 1.0f, 1.0f, 0.0f, 1.0f, tex.d[2], tex.d[3],
			pos.x + 0.0f, pos.y + 0.0f, pos.z + 0.0f, 1.0f, 1.0f, 0.0f, tex.d[0], tex.d[3],
			pos.x + 0.0f, pos.y + 1.0f, pos.z + 0.0f, 1.0f, 0.0f, 0.0f, tex.d[0], tex.d[1]
		});

		eb.addIndices(6, {
			i, i + 1, i + 3,
			i + 1, i + 2, i + 3
		});
		i += 4;

		tri_render_count += 2;
	
	}

}